from flask import Flask, render_template, Response, send_file
import cv2
import threading
import time
import numpy as np
import io
from PIL import Image, ImageDraw, ImageFont

app = Flask(__name__)

# 全局变量，用于控制摄像头状态
camera = None
output_frame = None
lock = threading.Lock()
camera_active = False

def generate_frames():
    """生成视频帧的函数"""
    global output_frame, camera, camera_active
    
    while True:
        with lock:
            if output_frame is None or not camera_active:
                time.sleep(0.1)  # 减少CPU使用率
                continue
            
            # 编码帧为JPEG
            (flag, encoded_image) = cv2.imencode(".jpg", output_frame)
            if not flag:
                continue

        # 以字节形式返回帧数据
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + bytearray(encoded_image) + b'\r\n')

def camera_thread():
    """摄像头线程函数"""
    global output_frame, camera, camera_active
    
    while True:
        if camera_active and camera is not None:
            success, frame = camera.read()
            if success:
                with lock:
                    output_frame = frame.copy()
        else:
            time.sleep(0.1)  # 减少CPU使用率
            
# 启动摄像头线程
threading.Thread(target=camera_thread, daemon=True).start()

@app.route('/')
def index():
    """渲染主页"""
    return render_template('index.html')

@app.route('/video_feed')
def video_feed():
    """视频流路由"""
    return Response(generate_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/start_camera')
def start_camera():
    """启动摄像头"""
    global camera, camera_active
    
    if camera is None:
        camera = cv2.VideoCapture(0)  # 打开默认摄像头
        time.sleep(0.5)  # 给摄像头一些时间来初始化
    
    camera_active = True
    return {"status": "success", "message": "摄像头已启动"}

@app.route('/stop_camera')
def stop_camera():
    """停止摄像头"""
    global camera_active
    
    camera_active = False
    return {"status": "success", "message": "摄像头已停止"}

@app.route('/static/img/placeholder.png')
def placeholder_image():
    """生成占位图像"""
    # 创建一个灰色背景图像
    img = Image.new('RGB', (640, 480), color=(238, 238, 238))
    draw = ImageDraw.Draw(img)
    
    # 绘制相机图标
    draw.rectangle([(640/2 - 50, 480/2 - 35), (640/2 + 50, 480/2 + 35)], fill=(153, 153, 153))
    draw.ellipse([(640/2 - 20, 480/2 - 20), (640/2 + 20, 480/2 + 20)], fill=(153, 153, 153))
    
    # 添加文字
    try:
        # 尝试加载中文字体
        font = ImageFont.truetype("simhei.ttf", 24)
    except IOError:
        # 如果找不到字体，使用默认字体
        font = ImageFont.load_default()
    
    draw.text((640/2, 480/2 + 80), "点击按钮打开摄像头", fill=(85, 85, 85), font=font, anchor="ms")
    
    # 将图像转换为字节流
    img_byte_arr = io.BytesIO()
    img.save(img_byte_arr, format='PNG')
    img_byte_arr.seek(0)
    
    return send_file(img_byte_arr, mimetype='image/png')

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000) 